LÀr dig skapa kraftfulla API-endpoints med Next.js Route Handlers. Guiden tÀcker allt frÄn grundlÀggande konfiguration till avancerade tekniker, med praktiska exempel.
Next.js Route Handlers: En Omfattande Guide till att Skapa API-Endpoints
Next.js har revolutionerat sÀttet vi bygger webbapplikationer pÄ med sina kraftfulla funktioner som server-side rendering, static site generation och nu, Route Handlers. Route Handlers erbjuder ett flexibelt och effektivt sÀtt att skapa API-endpoints direkt i din Next.js-applikation. Denna guide utforskar konceptet med Route Handlers, deras fördelar och hur man effektivt anvÀnder dem för att bygga robusta API:er.
Vad Àr Next.js Route Handlers?
Route Handlers Àr funktioner som definieras i app-katalogen i ett Next.js-projekt och hanterar inkommande HTTP-förfrÄgningar. Till skillnad frÄn det Àldre pages/api-tillvÀgagÄngssÀttet (som anvÀnder API Routes), erbjuder Route Handlers ett mer strömlinjeformat och flexibelt sÀtt att definiera API-endpoints vid sidan av dina React-komponenter. De Àr i grunden serverlösa funktioner som körs pÄ edge-nÀtverket eller i din valda servermiljö.
TÀnk pÄ Route Handlers som backend-logiken i din Next.js-applikation, ansvarig för att bearbeta förfrÄgningar, interagera med databaser och returnera svar.
Fördelar med att AnvÀnda Route Handlers
- Samlokalisering: Route Handlers ligger direkt bredvid dina React-komponenter i
app-katalogen, vilket frÀmjar bÀttre organisation och kodunderhÄll. - TypeScript-stöd: Inbyggt TypeScript-stöd sÀkerstÀller typsÀkerhet och en förbÀttrad utvecklarupplevelse.
- Middleware-integration: Integrera enkelt middleware för uppgifter som autentisering, auktorisering och validering av förfrÄgningar.
- Stöd för streaming: Route Handlers kan strömma data, vilket gör att du kan skicka svar inkrementellt, vilket Àr fördelaktigt för stora datamÀngder eller lÄngvariga processer.
- Edge Functions: DriftsÀtt Route Handlers som Edge Functions för lÄg latens och svar nÀrmare dina anvÀndare, med hjÀlp av globala CDN:er.
- Förenklad API-design: Route Handlers erbjuder ett rent och intuitivt API för att hantera förfrÄgningar och svar.
- Integration med Server Actions: TÀtt integration med Server Actions möjliggör sömlös kommunikation mellan dina klientkomponenter och serverlogik.
Konfigurera ditt Next.js-projekt
Innan du dyker in i Route Handlers, se till att du har ett Next.js-projekt konfigurerat med app-katalogen. Om du startar ett nytt projekt, anvÀnd följande kommando:
npx create-next-app@latest my-nextjs-app
VÀlj app-katalogen under installationsprocessen för att aktivera det nya routingsystemet.
Skapa din Första Route Handler
LÄt oss skapa en enkel API-endpoint som returnerar ett JSON-svar. Skapa en ny katalog i app-katalogen, till exempel /app/api/hello. Inuti denna katalog, skapa en fil med namnet route.ts (eller route.js om du inte anvÀnder TypeScript).
HÀr Àr koden för din första Route Handler:
// app/api/hello/route.ts
import { NextResponse } from 'next/server';
export async function GET(request: Request) {
return NextResponse.json({ message: 'Hej frÄn Next.js Route Handlers!' });
}
Förklaring:
import { NextResponse } from 'next/server';: ImporterarNextResponse-objektet, som anvÀnds för att konstruera API-svar.export async function GET(request: Request) { ... }: Definierar en asynkron funktion som hanterar GET-förfrÄgningar till/api/hello-endpointen.request-parametern ger tillgÄng till det inkommande förfrÄgningsobjektet.return NextResponse.json({ message: 'Hello from Next.js Route Handlers!' });: Skapar ett JSON-svar med ett meddelande och returnerar det medNextResponse.json().
Nu kan du komma Ät denna endpoint genom att navigera till /api/hello i din webblÀsare eller anvÀnda ett verktyg som curl eller Postman.
Hantera Olika HTTP-metoder
Route Handlers stöder olika HTTP-metoder som GET, POST, PUT, DELETE, PATCH och OPTIONS. Du kan definiera separata funktioner för varje metod i samma route.ts-fil.
// app/api/users/route.ts
import { NextResponse } from 'next/server';
export async function GET(request: Request) {
// Logik för att hÀmta alla anvÀndare frÄn databasen
const users = [{ id: 1, name: 'John Doe' }, { id: 2, name: 'Jane Smith' }]; // Exempeldata
return NextResponse.json(users);
}
export async function POST(request: Request) {
const data = await request.json(); // Tolka förfrÄgningens body som JSON
// Logik för att skapa en ny anvÀndare i databasen med 'data'
const newUser = { id: 3, name: data.name, email: data.email }; // Exempel
return NextResponse.json(newUser, { status: 201 }); // Returnera den nya anvÀndaren med statuskod 201 Created
}
Förklaring:
GET-funktionen hÀmtar en lista över anvÀndare (simulerat hÀr) och returnerar dem som ett JSON-svar.POST-funktionen tolkar förfrÄgningens body som JSON, skapar en ny anvÀndare (simulerat) och returnerar den nya anvÀndaren med statuskoden 201 Created.
à tkomst till FörfrÄgningsdata
request-objektet ger tillgÄng till diverse information om den inkommande förfrÄgningen, inklusive headers, query-parametrar och förfrÄgningens body.
Headers
Du kan komma Ät request-headers med egenskapen request.headers:
export async function GET(request: Request) {
const userAgent = request.headers.get('user-agent');
console.log('User Agent:', userAgent);
return NextResponse.json({ userAgent });
}
Query-parametrar
För att komma Ät query-parametrar kan du anvÀnda URL-konstruktorn:
export async function GET(request: Request) {
const url = new URL(request.url);
const searchParams = new URLSearchParams(url.search);
const id = searchParams.get('id');
console.log('ID:', id);
return NextResponse.json({ id });
}
Request Body
För POST-, PUT- och PATCH-förfrÄgningar kan du komma Ät förfrÄgningens body med metoderna request.json() eller request.text(), beroende pÄ innehÄllstyp.
export async function POST(request: Request) {
const data = await request.json();
console.log('Data:', data);
return NextResponse.json({ receivedData: data });
}
Returnera Svar
NextResponse-objektet anvÀnds för att konstruera API-svar. Det tillhandahÄller flera metoder för att stÀlla in headers, statuskoder och svarskroppar (response bodies).
JSON-svar
AnvÀnd metoden NextResponse.json() för att returnera JSON-svar:
return NextResponse.json({ message: 'Lyckades!', data: { name: 'John Doe' } }, { status: 200 });
Text-svar
AnvÀnd konstruktorn new Response() för att returnera rena text-svar:
return new Response('Hej, vÀrlden!', { status: 200, headers: { 'Content-Type': 'text/plain' } });
Omdirigeringar
AnvÀnd NextResponse.redirect() för att omdirigera anvÀndare till en annan URL:
import { redirect } from 'next/navigation';
import { NextResponse } from 'next/server';
export async function GET(request: Request) {
return NextResponse.redirect(new URL('/new-location', request.url));
}
StÀlla in Headers
Du kan stÀlla in anpassade headers med alternativet headers i NextResponse.json() eller new Response():
return NextResponse.json({ message: 'Lyckades!' }, { status: 200, headers: { 'Cache-Control': 'no-cache' } });
Middleware-integration
Middleware lÄter dig köra kod innan en förfrÄgan hanteras av din Route Handler. Detta Àr anvÀndbart för autentisering, auktorisering, loggning och andra övergripande aspekter (cross-cutting concerns).
För att skapa middleware, skapa en fil med namnet middleware.ts (eller middleware.js) i app-katalogen eller en underkatalog. Middleware-funktionen kommer att gÀlla för alla rutter inom den katalogen och dess underkataloger.
// app/middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
const token = request.cookies.get('auth-token');
if (!token) {
return NextResponse.redirect(new URL('/login', request.url));
}
return NextResponse.next();
}
export const config = {
matcher: ['/protected/:path*'], // TillÀmpa denna middleware pÄ sökvÀgar som börjar med /protected/
};
Förklaring:
middleware-funktionen kontrollerar om det finns en autentiseringstoken i förfrÄgningens cookies.- Om token saknas omdirigerar den anvÀndaren till inloggningssidan.
- Annars tillÄter den förfrÄgan att fortsÀtta till Route Handler.
config-objektet specificerar att denna middleware endast ska gÀlla för rutter som börjar med/protected/.
Felhantering
Korrekt felhantering Àr avgörande för att bygga robusta API:er. Du kan anvÀnda try...catch-block för att hantera undantag och returnera lÀmpliga felsvar.
export async function GET(request: Request) {
try {
// Simulera ett fel
throw new Error('NÄgot gick fel!');
} catch (error: any) {
console.error('Fel:', error);
return NextResponse.json({ error: error.message }, { status: 500 });
}
}
Förklaring:
try...catch-blocket fÄngar alla undantag som intrÀffar inom Route Handler.- I
catch-blocket loggas felet, och ett felsvar returneras med statuskoden 500 Internal Server Error.
Strömmande Svar (Streaming)
Route Handlers stöder strömmande svar, vilket lÄter dig skicka data inkrementellt till klienten. Detta Àr sÀrskilt anvÀndbart för stora datamÀngder eller lÄngvariga processer.
import { Readable } from 'stream';
import { NextResponse } from 'next/server';
async function* generateData() {
for (let i = 0; i < 10; i++) {
await new Promise(resolve => setTimeout(resolve, 500)); // Simulera fördröjning
yield `Datadel ${i}\n`;
}
}
export async function GET(request: Request) {
const readableStream = Readable.from(generateData());
return new Response(readableStream, {
headers: { 'Content-Type': 'text/plain; charset=utf-8' },
});
}
Förklaring:
- Funktionen
generateDataÀr en asynkron generator som producerar datadelar (yields) med en fördröjning. - Metoden
Readable.from()skapar en lÀsbar ström (readable stream) frÄn generatorn. Response-objektet skapas med den lÀsbara strömmen som body, ochContent-Type-headern sÀtts tilltext/plain.
Autentisering och Auktorisering
Att sÀkra dina API-endpoints Àr avgörande. Du kan implementera autentisering och auktorisering med hjÀlp av middleware eller direkt i dina Route Handlers.
Autentisering
Autentisering verifierar identiteten hos anvÀndaren som gör förfrÄgan. Vanliga autentiseringsmetoder inkluderar:
- JWT (JSON Web Tokens): Generera en token vid lyckad inloggning och verifiera den vid efterföljande förfrÄgningar.
- Sessionsbaserad autentisering: AnvÀnd cookies för att lagra sessionsidentifierare och verifiera dem vid varje förfrÄgan.
- OAuth: Delegera autentisering till en tredjepartsleverantör som Google eller Facebook.
HÀr Àr ett exempel pÄ JWT-autentisering med middleware:
// app/middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
import jwt from 'jsonwebtoken';
const secret = process.env.JWT_SECRET || 'din-hemliga-nyckel'; // ErsÀtt med ett starkt, slumpmÀssigt genererat hemligt nyckelord
export function middleware(request: NextRequest) {
const token = request.cookies.get('auth-token')?.value;
if (!token) {
return NextResponse.json({ message: 'Autentisering krÀvs' }, { status: 401 });
}
try {
jwt.verify(token, secret);
return NextResponse.next();
} catch (error) {
return NextResponse.json({ message: 'Ogiltig token' }, { status: 401 });
}
}
export const config = {
matcher: ['/api/protected/:path*'],
};
Auktorisering
Auktorisering bestÀmmer vilka resurser en anvÀndare har tillgÄng till. Detta baseras vanligtvis pÄ roller eller behörigheter.
Du kan implementera auktorisering inom dina Route Handlers genom att kontrollera anvÀndarens roller eller behörigheter och returnera ett fel om de inte har tillgÄng.
// app/api/admin/route.ts
import { NextResponse } from 'next/server';
export async function GET(request: Request) {
// Anta att du har en funktion för att hÀmta anvÀndarens roll frÄn token eller session
const userRole = await getUserRole(request);
if (userRole !== 'admin') {
return NextResponse.json({ message: 'Obehörig' }, { status: 403 });
}
// Logik för att hÀmta admindata
const adminData = { message: 'Admindata' };
return NextResponse.json(adminData);
}
async function getUserRole(request: Request): Promise {
// ErsÀtt med din faktiska logik för att extrahera anvÀndarens roll frÄn förfrÄgan
// Detta kan innebÀra att verifiera en JWT-token eller kontrollera en session
return 'admin'; // Exempel: hÄrdkodad roll för demonstration
}
DriftsÀttning av Route Handlers
Route Handlers driftsÀtts som serverlösa funktioner pÄ din valda hosting-leverantör. Next.js stöder olika driftsÀttningsplattformar, inklusive Vercel, Netlify, AWS och fler.
För Vercel Àr driftsÀttning sÄ enkelt som att ansluta ditt Git-repository till Vercel och pusha din kod. Vercel upptÀcker automatiskt ditt Next.js-projekt och driftsÀtter dina Route Handlers som serverlösa funktioner.
Avancerade Tekniker
Edge Functions
Route Handlers kan driftsÀttas som Edge Functions, som körs pÄ kanten av ett CDN, nÀrmare dina anvÀndare. Detta kan avsevÀrt minska latens och förbÀttra prestandan.
För att driftsÀtta en Route Handler som en Edge Function, lÀgg till edge runtime i din route.ts-fil:
export const runtime = 'edge';
import { NextResponse } from 'next/server';
export async function GET(request: Request) {
return NextResponse.json({ message: 'Hej frÄn Edge!' });
}
Server Actions
Server Actions lÄter dig köra server-side-kod direkt frÄn dina React-komponenter. Route Handlers och Server Actions fungerar sömlöst tillsammans, vilket gör att du enkelt kan bygga komplexa applikationer.
HÀr Àr ett exempel pÄ hur man anvÀnder en Server Action för att anropa en Route Handler:
// app/components/MyComponent.tsx
'use client';
import { useState } from 'react';
import { useRouter } from 'next/navigation';
async function handleSubmit(data: FormData) {
'use server';
const name = data.get('name');
const email = data.get('email');
const response = await fetch('/api/users', {
method: 'POST',
body: JSON.stringify({ name, email }),
});
if (response.ok) {
router.refresh(); // Uppdatera sidan för att visa Àndringarna
}
}
export default function MyComponent() {
const router = useRouter();
return (
);
}
Cachelagring
Cachelagring kan avsevÀrt förbÀttra prestandan för dina API-endpoints. Du kan anvÀnda Cache-Control-headern för att styra hur dina svar cachelagras av webblÀsare och CDN:er.
return NextResponse.json({ message: 'Lyckades!' }, { status: 200, headers: { 'Cache-Control': 'public, max-age=3600' } });
Detta exempel sÀtter Cache-Control-headern till public, max-age=3600, vilket talar om för webblÀsare och CDN:er att cachelagra svaret i en timme.
BĂ€sta Praxis
- AnvÀnd TypeScript: Dra nytta av TypeScripts typsÀkerhet för att förbÀttra kodkvaliteten och förhindra fel.
- Validera förfrÄgningar: Validera inkommande förfrÄgningar för att sÀkerstÀlla dataintegritet och förhindra skadlig indata.
- Hantera fel elegant: Implementera korrekt felhantering för att ge informativa felmeddelanden till klienter.
- SÀkra dina endpoints: Implementera autentisering och auktorisering för att skydda dina API-endpoints.
- AnvÀnd middleware: AnvÀnd middleware för övergripande aspekter som autentisering, loggning och validering av förfrÄgningar.
- Cachelagra svar: AnvÀnd cachelagring för att förbÀttra prestandan för dina API-endpoints.
- Ăvervaka dina API:er: Ăvervaka dina API:er för att snabbt identifiera och lösa problem.
- Dokumentera dina API:er: Dokumentera dina API:er för att göra dem enkla att anvĂ€nda för andra utvecklare. ĂvervĂ€g att anvĂ€nda verktyg som Swagger/OpenAPI för API-dokumentation.
Verkliga Exempel
HÀr Àr nÄgra verkliga exempel pÄ hur Route Handlers kan anvÀndas:
- E-handels-API: Skapa API-endpoints för att hantera produkter, ordrar och anvÀndare.
- Sociala medier-API: Skapa API-endpoints för att publicera inlÀgg, följa anvÀndare och hÀmta tidslinjer.
- API för innehÄllshanteringssystem (CMS): Skapa API-endpoints för att hantera innehÄll, anvÀndare och instÀllningar.
- Dataanalys-API: Skapa API-endpoints för att samla in och analysera data. Till exempel kan en Route Handler ta emot data frÄn spÄrningspixlar pÄ olika webbplatser och aggregera informationen för rapportering.
Exempel med internationell e-handel: En Route Handler som anvÀnds för att hÀmta produktpriser baserat pÄ anvÀndarens land. Endpointen kan anvÀnda förfrÄgningens geolokalisering (hÀrledd frÄn IP-adress) för att bestÀmma anvÀndarens plats och returnera priser i lÀmplig valuta. Detta bidrar till en lokaliserad shoppingupplevelse.
Exempel med global autentisering: En Route Handler som implementerar multifaktorautentisering (MFA) för anvÀndare vÀrlden över. Detta kan innebÀra att skicka SMS-koder eller anvÀnda autentiseringsappar, med respekt för olika regioners integritetslagstiftning och telekommunikationsinfrastrukturer.
Leverans av flersprÄkigt innehÄll: En Route Handler som levererar innehÄll pÄ anvÀndarens föredragna sprÄk. Detta kan bestÀmmas frÄn Accept-Language-headern i förfrÄgan. Detta exempel belyser behovet av korrekt UTF-8-kodning och stöd för sprÄk som skrivs frÄn höger till vÀnster dÀr det Àr lÀmpligt.
Sammanfattning
Next.js Route Handlers erbjuder ett kraftfullt och flexibelt sÀtt att skapa API-endpoints direkt i din Next.js-applikation. Genom att utnyttja Route Handlers kan du enkelt bygga robusta API:er, samlokalisera din backend-logik med dina React-komponenter och dra nytta av funktioner som middleware, streaming och Edge Functions.
Denna omfattande guide har tÀckt allt frÄn grundlÀggande konfiguration till avancerade tekniker. Genom att följa de bÀsta praxis som beskrivs i denna guide kan du bygga högkvalitativa API:er som Àr sÀkra, presterande och underhÄllbara.